package com.aek.ebey.sys.web.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.aek.common.core.Result;
import com.aek.common.core.base.BaseController;
import com.aek.common.core.util.WebUtil;
import com.aek.ebey.sys.core.BeanMapper;
import com.aek.ebey.sys.core.jackson.annotation.AllowProperty;
import com.aek.ebey.sys.core.jackson.annotation.IgnoreProperties;
import com.aek.ebey.sys.model.SysUser;
import com.aek.ebey.sys.model.query.UserQuery;
import com.aek.ebey.sys.model.vo.SysUserVo;
import com.aek.ebey.sys.service.SysUserService;
import com.aek.ebey.sys.web.request.UserRequest;
import com.aek.ebey.sys.web.validator.group.Add;
import com.aek.ebey.sys.web.validator.group.Edit;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author aek
 * @since 2017-05-06
 */
@RestController
@RequestMapping("/sys/user")
@Api(value = "SysUserController", description = "用户管理")
public class SysUserController extends BaseController {

	@Autowired
	private SysUserService sysUserService;

	/**
	 * 添加用户
	 * 
	 * @param data
	 * @param request
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_USER_NEW')")
	@PostMapping(value = "/add")
	@ApiOperation(value = "添加用户")
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Object> add(@Validated(value = Add.class) @RequestBody UserRequest data, HttpServletRequest request) {
		data.setId(null);
		SysUser user = BeanMapper.map(data, SysUser.class);
		user.setRegistrationIp(WebUtil.getHost(request));
		sysUserService.add(user);
		return response();
	}

	/**
	 * 修改个人用户信息
	 * 
	 * @param request
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_USER_MANAGE')")
	@PostMapping(value = "/edit")
	@ApiOperation(value = "修改用户")
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<SysUser> edit(@Validated(value = Edit.class) @RequestBody UserRequest request) {
		SysUser user = BeanMapper.map(request, SysUser.class);
		this.sysUserService.edit(user);
		return response(user);
	}

	/**
	 * 根据ID查询用户信息
	 * 
	 * @param id
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_USER_DETAILED_VIEW')")
	@GetMapping(value = "/{id}")
	@ApiOperation(value = "查看用户详细信息")
	@ApiImplicitParam(name = "id", value = "用户ID", paramType = "path", required = true)
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<SysUserVo> findById(@PathVariable(value = "id", required = true) Long id) {
		SysUserVo userVo = null;
		SysUser sysUser = this.sysUserService.selectById(id);
		if (sysUser != null) {
			userVo = BeanMapper.map(sysUser, SysUserVo.class);
		}
		return response(userVo);
	}

	@PreAuthorize("hasAuthority('SYS_USER_MANAGE')")
	@PostMapping(value = "/{id}/changePwd")
	@ApiOperation(value = "修改用户密码")
	@ApiImplicitParam(name = "id", value = "用户ID", paramType = "path", required = true)
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Object> changePassword(@PathVariable(required = true, value = "id") Long id,
			@RequestBody String password) {
		boolean flag = this.sysUserService.changePassword(id, password);
		if (!flag) {
			return responseMsg("U_016");
		}
		return response();
	}

	@PreAuthorize("hasAuthority('SYS_USER_MANAGE')")
	@PostMapping(value = "/disable/{id}")
	@ApiOperation(value = "根据id停用用户")
	@ApiImplicitParam(name = "id", value = "用户ID", paramType = "path", required = true)
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Object> disable(@PathVariable(value = "id", required = true) Long id) {
		SysUser entity = new SysUser();
		entity.setEnable(false);
		entity.setUpdateTime(new Date());
		Wrapper<SysUser> wrapper = new EntityWrapper<SysUser>();
		wrapper.eq("id", id);
		wrapper.eq("del_flag", false);
		wrapper.eq("enable", true);
		boolean flag = this.sysUserService.update(entity, wrapper);
		if (flag) {
			return response();
		} else {
			return responseMsg("U_017");
		}
	}

	/**
	 * 根据ID查询用户信息
	 * 
	 * @param id
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_USER_MANAGE')")
	@DeleteMapping(value = "/delete/{id}")
	@ApiOperation(value = "根据id删除用户", httpMethod = "DELETE")
	@ApiImplicitParam(name = "id", value = "用户ID", paramType = "path", required = true)
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Object> deleteById(@PathVariable(value = "id", required = true) Long id) {
		SysUser entity = new SysUser();
		entity.setDelFlag(true);
		entity.setUpdateTime(new Date());
		Wrapper<SysUser> wrapper = new EntityWrapper<SysUser>();
		wrapper.eq("id", id);
		wrapper.eq("del_flag", false);
		boolean flag = this.sysUserService.update(entity, wrapper);
		if (flag) {
			return response();
		} else {
			return responseMsg("U_009");
		}
	}

	/**
	 * 查询用户列表
	 * 
	 * @param keyword
	 *            关键字
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_USER_DEPT_VIEW')")
	@IgnoreProperties(allow = { @AllowProperty(pojo = SysUser.class, name = { "id", "realName", "mobile", "email",
			"mobile", "deptName", "jobName", "enable", "createTime" }) })
	@GetMapping(value = "/search")
	@ApiOperation(value = "查询用户列表(分页)", httpMethod = "GET", produces = "application/json")
	@ApiImplicitParams({ @ApiImplicitParam(name = "pageNo", value = "起始页 [默认1]", paramType = "query", required = false),
			@ApiImplicitParam(name = "pageSize", value = "分页大小[默认10]", paramType = "query", required = false),
			@ApiImplicitParam(name = "tenantId", value = "租户ID [必须]", paramType = "query", required = true),
			@ApiImplicitParam(name = "enable", value = "启用未启用[true=启用,false=未启用]", paramType = "query", required = false),
			@ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "query", required = false),
			@ApiImplicitParam(name = "keyword", value = "关键字", paramType = "query", required = false) })
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Page<SysUser>> search(UserQuery query) {
		Page<SysUser> page = this.sysUserService.search(query);
		return response(page);
	}

	/**
	 * 根据机构ID查询用户列表
	 * 
	 * @param enable
	 *            用户状态
	 * 
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_TENANT_MANAGE')")
	@RequestMapping(value = "/users/tenantId", method = RequestMethod.GET)
	@ApiOperation(value = "查询租户下的用户列表", httpMethod = "GET", produces = "application/json")
	@ApiImplicitParam(name = "tenantId", value = "机构ID", paramType = "query", required = true)
	@ApiResponse(code = 0, message = "OK", response = Result.class)
	public Result<List<SysUser>> findUserByTenantId(@RequestParam(value = "tenantId") Long tenantId,
			@RequestParam(value = "enable", required = false) Boolean enable) {
		List<SysUser> users = this.sysUserService.findByTenantId(tenantId, enable);
		return response(users);
	}

	/**
	 * 根据ID查询用户信息
	 * 
	 * @param id
	 * @return
	 */
	@PreAuthorize("hasAuthority('SYS_USER_MANAGE')")
	@PostMapping(value = "/recover/{id}")
	@ApiOperation(value = "根据id恢复用户")
	@ApiImplicitParam(name = "id", value = "用户ID", paramType = "path", required = true)
	@ApiResponse(code = 200, message = "OK", response = Result.class)
	public Result<Object> recoverAble(@PathVariable(value = "id", required = true) Long id) {
		SysUser entity = new SysUser();
		entity.setEnable(true);
		entity.setUpdateTime(new Date());
		Wrapper<SysUser> wrapper = new EntityWrapper<SysUser>();
		wrapper.eq("id", id);
		wrapper.eq("del_flag", false);
		wrapper.eq("enable", false);
		boolean flag = this.sysUserService.update(entity, wrapper);
		if (flag) {
			return response();
		} else {
			return responseMsg("U_018");
		}
	}
}
